package com.agh.szepczynski.magisterka.service.algorithms;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.agh.szepczynski.magisterka.service.beans.dm.Person;
import com.agh.szepczynski.magisterka.service.beans.dto.EventAlgorithm;
import com.agh.szepczynski.magisterka.service.beans.dto.PersonProgress;
import com.agh.szepczynski.magisterka.service.events.AlgorithmState;

public class AlgorithmBars implements IContestAlghoritm {

	protected static final Log logger = LogFactory.getLog(AlgorithmBars.class);
	Random random = new Random();
	private List<PersonProgress> peopleProgresses = new ArrayList<PersonProgress>();
	private List<Person> people;
	private int WINNERS_COUNT; 

	private List<PersonProgress> createPeopleProgresses() {
		ArrayList<PersonProgress> peopleProgresses = new ArrayList<PersonProgress>();
		for (Person person : getPeople()) {
			PersonProgress personProgress = new PersonProgress();
			personProgress.setId(person.getId());
			personProgress.setPercentFinished(0);
			peopleProgresses.add(personProgress);
		}
		return peopleProgresses;

	}

	synchronized public List<PersonProgress> getPeopleProgresses() {
		return peopleProgresses;
	}



	@Override
	public boolean isEnded() {
		for (PersonProgress personProgress : peopleProgresses) {
			if (personProgress.getPercentFinished() >= 100) {
				logger.info("Algorithm has ended");
				return true;
			}
		}
		return false;
	}

	@Override
	public void nextStep() {
		updatePeopleProgresses();
	}

	synchronized public void setPeopleProgresses(
			List<PersonProgress> peopleProgresses) {
		this.peopleProgresses = peopleProgresses;
	}

	private void updatePeopleProgresses() {
		logger.debug("Updating people progresses");
		int currentWinners=0;
		for (PersonProgress personProgress : peopleProgresses) {
			Integer percentFinished = personProgress.getPercentFinished();
			int MIN = 5;
			int MAX = 15;
			percentFinished += random.nextInt(MAX-MIN)+MIN;
			if(percentFinished>=100){
				percentFinished=100;
				currentWinners++;
			}
			personProgress.setPercentFinished(percentFinished);
			
			if(currentWinners>=WINNERS_COUNT){
				logger.debug("Got all winners, stopping updating people progressess..");
				break;
			}
		}
		logger.debug(peopleProgresses);
	}

	@Override
	public List<Person> getWinners() throws Exception {
		List<Person> winners = new ArrayList<Person>();
		if (isEnded()) {
			for (PersonProgress personProgress : peopleProgresses) {
					if(personProgress.getPercentFinished()>=100){
						for (Person person : winners) {
							if(person.getId()==personProgress.getId()){
								winners.add(person);
								break;
							}
						}
					}
			}
			logger.info("Winners: "+winners);
			return winners;
		} else {
			throw new Exception("Algorithm hasnt ended yet");
		}
	}

	@Override
	public AlgorithmState getAlgorithmState() {
		AlgorithmState algorithmState = new AlgorithmState();
		algorithmState.setPeopleProgresses(peopleProgresses);
		return algorithmState;
	}

	public List<Person> getPeople() {
		return people;
	}

	public void setPeople(List<Person> people) {
		this.people = people;
	}

	@Override
	public void init(List<Person> people, int winnersCount) {
		this.WINNERS_COUNT = winnersCount;
		setPeople(people);
		peopleProgresses = createPeopleProgresses();		
	}

	@Override
	public EventAlgorithm getName() {
		return EventAlgorithm.ALGORITHM_BARS;
	}

}
